package cn.iocoder.yudao.module.pplan.service.shiftrecord;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjUtil;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.module.pplan.controller.admin.shiftrecord.vo.*;
import cn.iocoder.yudao.module.pplan.dal.dataobject.shiftrecord.ShiftRecordDO;
import cn.iocoder.yudao.module.pplan.dal.mysql.shiftrecord.ShiftRecordMapper;
import cn.iocoder.yudao.module.system.dal.dataobject.user.AdminUserDO;
import cn.iocoder.yudao.module.system.dal.mysql.user.AdminUserMapper;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;

import javax.annotation.Resource;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.module.pplan.enums.ErrorCodeConstants.SHIFT_RECORD_EXISTS;
import static cn.iocoder.yudao.module.pplan.enums.ErrorCodeConstants.SHIFT_RECORD_NOT_EXISTS;
/**
 * 排班管理 Service 实现类
 *
 * @author yisl
 */
@Service
@Validated
public class ShiftRecordServiceImpl implements ShiftRecordService {

    @Resource
    private ShiftRecordMapper shiftRecordMapper;

    @Resource
    private AdminUserMapper userMapper;

    @Override
    public Long createShiftRecord(ShiftRecordSaveReqVO createReqVO) {

        // 插入
        validateShiftRecordExists(createReqVO.getShiftDate());
        ShiftRecordDO shiftRecord = BeanUtils.toBean(createReqVO, ShiftRecordDO.class);
        if (CollUtil.isNotEmpty(createReqVO.getShiftUsers())){
            shiftRecord.setMorningShiftDriver(createReqVO.getShiftUsers().get(0).getShiftDriver());
            shiftRecord.setMorningShiftSupport(createReqVO.getShiftUsers().get(0).getShiftSupport());
            shiftRecord.setMorningShiftCrew(createReqVO.getShiftUsers().get(0).getShiftCrew());
            if (createReqVO.getShiftUsers().size()>1){
                shiftRecord.setMiddleShiftDriver(createReqVO.getShiftUsers().get(1).getShiftDriver());
                shiftRecord.setMiddleShiftSupport(createReqVO.getShiftUsers().get(1).getShiftSupport());
                shiftRecord.setMiddleShiftCrew(createReqVO.getShiftUsers().get(1).getShiftCrew());
            }
            if (createReqVO.getShiftUsers().size()>2){
                shiftRecord.setNightShiftDriver(createReqVO.getShiftUsers().get(2).getShiftDriver());
                shiftRecord.setNightShiftSupport(createReqVO.getShiftUsers().get(2).getShiftSupport());
                shiftRecord.setNightShiftCrew(createReqVO.getShiftUsers().get(2).getShiftCrew());
            }
        }

        shiftRecordMapper.insert(shiftRecord);
        // 返回
        return shiftRecord.getId();
    }

    @Override
    public void updateShiftRecord(ShiftRecordSaveReqVO updateReqVO) {
        // 校验存在
        validateShiftRecordExists(updateReqVO.getId());
        validateShiftRecordExists(updateReqVO);

        // 更新
        ShiftRecordDO updateObj = BeanUtils.toBean(updateReqVO, ShiftRecordDO.class);
        if (CollUtil.isNotEmpty(updateReqVO.getShiftUsers())){
            updateObj.setMorningShiftDriver(updateReqVO.getShiftUsers().get(0).getShiftDriver());
            updateObj.setMorningShiftSupport(updateReqVO.getShiftUsers().get(0).getShiftSupport());
            updateObj.setMorningShiftCrew(updateReqVO.getShiftUsers().get(0).getShiftCrew());
            if (updateReqVO.getShiftUsers().size()>1){
                updateObj.setMiddleShiftDriver(updateReqVO.getShiftUsers().get(1).getShiftDriver());
                updateObj.setMiddleShiftSupport(updateReqVO.getShiftUsers().get(1).getShiftSupport());
                updateObj.setMiddleShiftCrew(updateReqVO.getShiftUsers().get(1).getShiftCrew());
            }
            if (updateReqVO.getShiftUsers().size()>2){
                updateObj.setNightShiftDriver(updateReqVO.getShiftUsers().get(2).getShiftDriver());
                updateObj.setNightShiftSupport(updateReqVO.getShiftUsers().get(2).getShiftSupport());
                updateObj.setNightShiftCrew(updateReqVO.getShiftUsers().get(2).getShiftCrew());
            }
        }
        shiftRecordMapper.updateById(updateObj);
    }

    @Override
    public void deleteShiftRecord(Long id) {
        // 校验存在
        validateShiftRecordExists(id);
        // 删除
        shiftRecordMapper.deleteById(id);
    }

    @Override
        public void deleteShiftRecordListByIds(List<Long> ids) {
        // 校验存在
        validateShiftRecordExists(ids);
        // 删除
        shiftRecordMapper.deleteByIds(ids);
        }

    private void validateShiftRecordExists(List<Long> ids) {
        List<ShiftRecordDO> list = shiftRecordMapper.selectByIds(ids);
        if (CollUtil.isEmpty(list) || list.size() != ids.size()) {
            throw exception(SHIFT_RECORD_NOT_EXISTS);
        }
    }

    private void validateShiftRecordExists(Long id) {
        if (shiftRecordMapper.selectById(id) == null) {
            throw exception(SHIFT_RECORD_NOT_EXISTS);
        }
    }

    private void validateShiftRecordExists(LocalDate date) {
        if (shiftRecordMapper.selectOne(ShiftRecordDO::getShiftDate, date) != null) {
            throw exception(SHIFT_RECORD_EXISTS);
        }
    }

    private void validateShiftRecordExists(ShiftRecordSaveReqVO update) {
        ShiftRecordDO shiftRecordDO = shiftRecordMapper.selectOne(ShiftRecordDO::getShiftDate, update.getShiftDate());
        if (shiftRecordDO != null) {
            if (!shiftRecordDO.getId().equals(update.getId())) {
                throw exception(SHIFT_RECORD_EXISTS);
            }
        }
    }

    @Override
    public ShiftRecordRespVO getShiftRecord(String date) {
        ShiftRecordDO shiftRecordDO = shiftRecordMapper.selectOne(ShiftRecordDO::getShiftDate, LocalDate.parse(date));
        ShiftRecordRespVO shiftRecordRespVO = BeanUtils.toBean(shiftRecordDO, ShiftRecordRespVO.class);
        if (ObjUtil.isEmpty(shiftRecordRespVO)){
            throw exception(SHIFT_RECORD_NOT_EXISTS);
        }
        // 2. 转成list
        List<ShiftUserSimpleReqVO> users = new ArrayList<>(3);
        ShiftUserSimpleReqVO moring = new ShiftUserSimpleReqVO();
        moring.setShiftDriver(shiftRecordDO.getMorningShiftDriver());
        moring.setShiftSupport(shiftRecordDO.getMorningShiftSupport());
        moring.setShiftCrew(shiftRecordDO.getMorningShiftCrew());
        users.add(0, moring);
        ShiftUserSimpleReqVO middle = new ShiftUserSimpleReqVO();
        middle.setShiftDriver(shiftRecordDO.getMiddleShiftDriver());
        middle.setShiftSupport(shiftRecordDO.getMiddleShiftSupport());
        middle.setShiftCrew(shiftRecordDO.getMiddleShiftCrew());
        users.add(1, middle);
        ShiftUserSimpleReqVO night = new ShiftUserSimpleReqVO();
        night.setShiftDriver(shiftRecordDO.getNightShiftDriver());
        night.setShiftSupport(shiftRecordDO.getNightShiftSupport());
        night.setShiftCrew(shiftRecordDO.getNightShiftCrew());
        users.add(2, night);
        shiftRecordRespVO.setShiftUsers(users);
        return shiftRecordRespVO;
    }

    @Override
    public List<ShiftRecordSimpleRespVO> getShiftRecordSimple(String shiftDate) {
        ShiftRecordDO shiftRecordDO = shiftRecordMapper.selectOne(ShiftRecordDO::getShiftDate, LocalDate.parse(shiftDate));
        if (ObjUtil.isEmpty(shiftRecordDO)|| ObjUtil.isEmpty(shiftRecordDO.getMorningShiftDriver())
                || ObjUtil.isEmpty(shiftRecordDO.getMorningShiftCrew())
                || ObjUtil.isEmpty(shiftRecordDO.getMorningShiftSupport())){
            return Collections.emptyList();
        }
        // 1.获取用户id
        List<Long> ids = Stream.of(shiftRecordDO.getMorningShiftDriver(),shiftRecordDO.getMorningShiftCrew(),
                shiftRecordDO.getMorningShiftSupport(),shiftRecordDO.getMiddleShiftDriver(),shiftRecordDO.getMiddleShiftCrew(),
                shiftRecordDO.getMiddleShiftSupport(),shiftRecordDO.getNightShiftDriver(),shiftRecordDO.getNightShiftCrew(),
                shiftRecordDO.getNightShiftSupport()).distinct().collect(Collectors.toList());
        List<AdminUserDO> adminUserDOS = userMapper.selectList(AdminUserDO::getId, ids);
        Map<Long, AdminUserDO> userDOMap = CollectionUtils.convertMap(adminUserDOS, AdminUserDO::getId);
        // 2. 转成list
        List<ShiftRecordSimpleRespVO> users = new ArrayList<>(3);
        ShiftRecordSimpleRespVO moring = new ShiftRecordSimpleRespVO();
        moring.setShiftRecordIds("["+shiftRecordDO.getMorningShiftDriver()+"]["
                +shiftRecordDO.getMorningShiftCrew()+"]["+shiftRecordDO.getMorningShiftSupport()+"]");
        moring.setShiftRecordNames(userDOMap.get(shiftRecordDO.getMorningShiftDriver()).getNickname()+","
                +userDOMap.get(shiftRecordDO.getMorningShiftCrew()).getNickname()+","
                +userDOMap.get(shiftRecordDO.getMorningShiftSupport()).getNickname());
        users.add(0, moring);
        ShiftRecordSimpleRespVO middle = new ShiftRecordSimpleRespVO();
        middle.setShiftRecordIds("["+shiftRecordDO.getMiddleShiftDriver()+"]["
                +shiftRecordDO.getMiddleShiftCrew()+"]["+shiftRecordDO.getMiddleShiftSupport()+"]");
        middle.setShiftRecordNames(userDOMap.get(shiftRecordDO.getMiddleShiftDriver()).getNickname()+","
                +userDOMap.get(shiftRecordDO.getMiddleShiftCrew()).getNickname()+","
                +userDOMap.get(shiftRecordDO.getMiddleShiftSupport()).getNickname());
        users.add(1, middle);
        ShiftRecordSimpleRespVO night = new ShiftRecordSimpleRespVO();
        night.setShiftRecordIds("["+shiftRecordDO.getNightShiftDriver()+"]["
                +shiftRecordDO.getNightShiftCrew()+"]["+shiftRecordDO.getNightShiftSupport()+"]");
        night.setShiftRecordNames(userDOMap.get(shiftRecordDO.getNightShiftDriver()).getNickname()+","
                +userDOMap.get(shiftRecordDO.getNightShiftCrew()).getNickname()+","
                +userDOMap.get(shiftRecordDO.getNightShiftSupport()).getNickname());
        users.add(2, night);
        return users;
    }

    @Override
    public PageResult<ShiftRecordRespVO> getShiftRecordPage(ShiftRecordPageReqVO pageReqVO) {
        PageResult<ShiftRecordDO> shiftRecordDOPageResult = shiftRecordMapper.selectPage(pageReqVO);
        return new PageResult<>(buildDetailList(shiftRecordDOPageResult.getList()), shiftRecordDOPageResult.getTotal());
    }

    private List<ShiftRecordRespVO> buildDetailList(List<ShiftRecordDO> list) {
        if (CollUtil.isEmpty(list)) {
            return Collections.emptyList();
        }
        return BeanUtils.toBean(list, ShiftRecordRespVO.class);
    }

}